
#include <BMouseEvent>
#include <BChangeEvent>
#include <BStyle>
#include <BPainter>
#include <BOpenGL>

#include <BColorDialog>
#include "member_BColorDialog.h"

using namespace BWE;

#define member					(*(member_BColorDialog*)_ptr)
#define member_allocate()		_ptr = new member_BColorDialog(this)
#define member_release()		delete (member_BColorDialog*)_ptr

BColorDialog::BColorDialog(BWidget* parent) : BDialog(parent)
{
	member_allocate();
}
BColorDialog::~BColorDialog()
{
	member_release();
}

void BColorDialog::setColor(const BColor& color)
{
	member.color = color;

	BByte max = bMax(member.color.r(), bMax(member.color.g(), member.color.b()));
	double scale = 255.0 / max;
	member.grayColor.r() = (BByte)(member.color.r() * scale);
	member.grayColor.g() = (BByte)(member.color.g() * scale);
	member.grayColor.b() = (BByte)(member.color.b() * scale);
	member.grayColor.a() = member.color.a();
	this->fresh();
}
const BColor& BColorDialog::color() const
{
	return member.color;
}

void BColorDialog::showEvent(const BEvent& event)
{
	hintSize(Part_Bottom);
	BDialog::showEvent(event);
}

void BColorDialog::changeEvent(const BChangeEvent& event)
{
	BDialog::changeEvent(event);

	if (event.change() == Change_Style)
	{
		const BStyle* style = event.style();
		member.okButton->setImage(style->image("button-ok"));
		member.cancleButton->setImage(style->image("button-cancel"));
	}
}
void BColorDialog::freshEvent(const BEvent& event)
{
	BDialog::freshEvent(event);
	member.freshWidgets();
	member.freshGraph();
}

void BColorDialog::paintEvent(const BEvent& event)
{
	BDialog::paintEvent(event);

	BPainter painter(this);

	BRect drawRect = member.drawSpacer->rect();
	BRect grayRect = member.graySpacer->rect();

	BByte blue = member.color.b();
	glBegin(GL_QUADS);
	{
		glColor3ub(0, 0, blue);
		glVertex2i(drawRect.x(), drawRect.y());
		glColor3ub(255, 0, blue);
		glVertex2i(drawRect.x(), drawRect.bottom());
		glColor3ub(255, 255, blue);
		glVertex2i(drawRect.right(), drawRect.bottom());
		glColor3ub(0, 255, blue);
		glVertex2i(drawRect.right(), drawRect.y());
	}
	glEnd();

	glBegin(GL_QUADS);
	{
		glColor3ub(member.grayColor.r(), member.grayColor.g(), member.grayColor.b());
		glVertex2i(grayRect.right(), grayRect.y());
		glVertex2i(grayRect.x(), grayRect.y());
		glColor3f(0, 0, 0);
		glVertex2i(grayRect.x(), grayRect.bottom());
		glVertex2i(grayRect.right(), grayRect.bottom());
	}
	glEnd();

	painter.setColor(255, 255, 255);
	painter.fillRect(member.colorSpacer->rect() * 0.88);

	painter.setColor(member.color);
	painter.fillRect(member.colorSpacer->rect() * 0.5);

	painter.setColor(255, 255, 255);
	painter.drawRect(member.colorRect);
	painter.drawRect(member.grayHandle);
}

void BColorDialog::mousePressEvent(const BMouseEvent& mouseEvent)
{
	BDialog::mousePressEvent(mouseEvent);
	const BPoint& pos = mouseEvent.pos();
	BRect drawRect = member.drawSpacer->rect();
	BRect grayRect = member.graySpacer->rect();
	if (drawRect.contain(pos))
	{
		float r = (float)(pos.y() - drawRect.y()) / drawRect.height();
		float g = (float)(pos.x() - drawRect.x()) / drawRect.width();
		BColor color(r * 255, g * 255, member.blueSpinBox->value());
		setColor(color);
	}
	if (grayRect.contain(pos))
	{
		float gray = (float)(grayRect.bottom() - pos.y()) / grayRect.height();
		BColor color = member.grayColor * gray;
		color.a() = member.alphaSpinBox->value();
		setColor(color);
	}
}
